import { useState, useEffect } from "react"

// Effect 副作用的意思   使用副作用
// let arr = ["a","b"]; arr.push("c")   ["a","b","c"]
// 调用push，改变了原数组。那么就说push方法有副作用。
// 发ajax请求，DOM操作都是有副作用。  let res = [];
// useEffect，之前处理副作用，代码一般是写在生命周期函数中的
// 在函数式组件中，使用useEffect来处理副作用。
// 所以有人就说useEffect就是模拟类组件中的生命周期函数的。
// componentDidMount/componentDidUpdate/componentWillUnmount

const A = props => {
  const [num, setNum] = useState(1)
  const [count, setCount] = useState(1)

  // fn1中就可以书写副作用
  // fn2中就可以清除副作用
  // 格式：useEffect(fn1，fn1中需要返回fn2,[依赖])
  // useEffect(() => {
  //   // ... 书写副作用
  //   return () => {
  //     // fn2 ... 清除副作用
  //   }
  // },[])

  // 当没有“依赖数组”这个参数时，初始化只执行fn1，当re-render时，先执行fn2，再执行fn1。
  // fn1 类似于 componentDidMount
  // 没有“依赖数组”，当任意状态发生了变化都会执行fn2 fn1
  // useEffect(() => {
  //   console.log("fn1...");
  //   return () => {
  //     console.log("fn2...");
  //   }
  // })

  // 当有“依赖数组”这个参数时，但是是一个空数组，初始化只执行fn1，当re-render时，什么也不执行。
  // 这样写，类似于componentDidMount
  // useEffect(() => {
  //   console.log("fn1...");
  //   return () => {
  //     console.log("fn2...");
  //   }
  // },[])

  // 当有“依赖数组”这个参数时，但是不是一个空数组，初始化只执行fn1。有且仅有当“依赖数组"中的变量发生变化导致rerender时，先执行fn2，再执行fn1()。
  // useEffect(() => {
  //   console.log("fn1...");
  //   return () => {
  //     console.log("fn2...");
  //   }
  // }, [num, count])

  return (
    <div>
      <h2>函数式组件</h2>
      <h3>{num}</h3>
      <button onClick={() => setNum(num + 1)}>+1</button>
      <hr />
      <h3>{count}</h3>
      <button onClick={() => setCount(count + 1)}>+1</button>
    </div>
  )
}

export default A;

// useEffect()
//  语法格式：useEffect(fn1,fn1函数中returnfn2,[依赖数组])
//  执行情况1：没有依赖数据，挂载时，执行fn1，更新时，先fn2，再fn1。路由切换，只执行fn2。
//  执行情况2：有依赖数据，是一个[]，挂载时，执行fn1，更新时，fn1和fn2都不执行。路由切换，只执行fn2。
//  执行情况3：有依赖数据，不是空数组，是[num]，挂载时，执行fn1，只有num更新时，先fn2，再fn1。。路由切换，只执行fn2。
//  fn1相当于类组件中的 componentDidMount
//  fn2相当于类组件中的 componentWillUnMount
//  如果有依赖数据，相当于类组件中的 componentDidUpdate